package com.magenta.maxoptra.routing;

import java.net.URL;

/**
 * @author ivictus
 *
 */
/**
 * Redefine some equals and hashCode methods.
 */
public final class HashMapUtil {

	/**
	 * Non blocking equals.
	 * @param url1
	 * @param url2
	 * @return true if urls are having same protocols, hosts, ports and paths.
	 */
	public static boolean equals(URL url1, URL url2) {
		//OPTIMISTIC OPTIMIZATION
		if (url1 == url2) {
			return true;
		}
		//PESEMISTIC OPTIMIZATIONS
		if (url1 == null ^ url2 == null) {
			return false;
		}
		if (!eq(url1.getHost(), url2.getHost())) {
			return false;
		}
		if (!eq(url1.getProtocol(), url2.getProtocol())) {
			return false;
		}
		if (!eq(url1.getPort(), url2.getPort())) {
			return false;
		}
		if (!eq(url1.getPath(), url2.getPath())) {
			return false;
		}
		//OTHERWISE URL1, URL2 ARE EQUALS
		return true;
	}

	private static boolean eq(Object obj1, Object obj2) {
		return obj1 == obj2 || (obj1 != null && obj1.equals(obj2));
	}
	
	/**
	 * Nonblocking hash code.
	 * @param url
	 * @return hash
	 */
	public static int hashCode(URL url) {
		if (url == null) {
			return 0;
		}
		return hash(url.getHost(), 0) ^
			hash(url.getPort(), 3) ^
			hash(url.getProtocol(), 5) ^
			hash(url.getPath(), 7);
	}

	private static int hash(Object obj, int shift) {
		//HASH OF null IS ZERO.
		if (obj == null) {
			return 0;
		}
		int i = obj.hashCode();
		//OUT OF RANGE - NO SHIFTING
		if (i < 1 || i > 31) {
			return i;
		}
		return ((i >>> shift) | (i << 32 - shift));
	}
	
	
	
}
